use std::borrow::Cow;

use axum::extract::rejection::BytesRejection;
use thiserror::Error;

pub type IoErr = std::io::Error;
pub type SqlxErr = sqlx::Error;

#[derive(Debug, Error)]
pub enum AppErr {
    #[error("sqlx:{0}")]
    Sqlx(#[from] SqlxErr),

    #[error("io:{0}")]
    Io(#[from] IoErr),

    #[error("bytes:{0}")]
    Bytes(#[from] BytesRejection),

    #[error("cbor:{0}")]
    Cbor(#[from] serde_cbor::Error),

    #[error("{0}=>{1}")]
    Service(i32, Cow<'static, str>),
}

pub const EC_WAIT_TIMEOUT: i32 = 1;
pub const EC_UNKNOWN: i32 = 2;
pub const EC_ALREADY_VOTE: i32 = 3;

pub fn is_unique_violation(err: &SqlxErr) -> bool {
    match err {
        SqlxErr::Database(e) => e.is_unique_violation(),
        _ => false,
    }
}

pub fn new_error(msg: &'static str) -> AppErr {
    AppErr::Service(-1, Cow::Borrowed(msg))
}

